home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Format / p2explode / explode_chan.c next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  8.1 KB  |  329 lines

  1. /* p2explode: channel to explode a P2 message into body parts */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Format/p2explode/RCS/explode_chan.c,v 6.0 1991/12/18 20:20:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Format/p2explode/RCS/explode_chan.c,v 6.0 1991/12/18 20:20:02 jpo Rel $
  9.  *
  10.  * $Log: explode_chan.c,v $
  11.  * Revision 6.0  1991/12/18  20:20:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "util.h"
  19. #include "qmgr.h"
  20. #include "q.h"
  21. #include "prm.h"
  22. #include "retcode.h"
  23. #include "tb_bpt88.h"
  24. #include "dr.h"
  25. #include <sys/stat.h>
  26. #include "sys.file.h"
  27. #include <isode/cmd_srch.h>
  28.  
  29. extern CMD_TABLE bptbl_body_parts88[/* x400 84 body_parts */];
  30. extern char    *quedfldir;
  31. extern CHAN    *ch_nm2struct();
  32. extern char    *cont_p2;
  33. extern void    rd_end(), sys_init(), err_abrt();
  34. extern struct type_Qmgr_DeliveryStatus    *delivery_resetDRs();
  35. extern int    err_fatal;
  36. static CHAN    *mychan;
  37. static char    *this_msg, *this_chan;
  38.  
  39. static int    processMsg();
  40. static int    doSplit();
  41. static struct type_Qmgr_DeliveryStatus    *process();
  42. static int                initialise();
  43. static int                security_check(), x40084;
  44. static void                dirinit();
  45. static ADDR                *getnthrecip ();
  46. int first_failureDR;
  47. /*   */
  48. /* main routine */
  49.  
  50. main(argc, argv)
  51. int     argc;
  52. char    **argv;
  53. {
  54.     sys_init(argv[0]);
  55.     dirinit ();
  56. #ifdef PP_DEBUG
  57.     if (argc>1 && (strcmp(argv[1],"debug") == 0))
  58.         debug_channel_control (argc, argv, initialise, process, NULLIFP);
  59.     else
  60. #endif
  61.     channel_control(argc, argv, initialise, process, NULLIFP);
  62. }
  63.  
  64. /*   */
  65. /* move to correct place in file system */
  66.  
  67. static void dirinit ()
  68. {
  69.     if (chdir (quedfldir) < 0)
  70.         err_abrt( RP_LIO, " Unable to change directory to '%s'",
  71.             quedfldir);
  72. }
  73.  
  74. /*   */
  75. /* channel initialise routine */
  76.  
  77. static int initialise (arg)
  78. struct type_Qmgr_Channel    *arg;
  79. {
  80.     char    *name;
  81.  
  82.     name = qb2str(arg);
  83.  
  84.     if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
  85.         PP_OPER(NULLCP, 
  86.             ("Chans/p2explode : Channel '%s' not known",name));
  87.         if (name != NULL) free(name);
  88.         return NOTOK;
  89.     }
  90.  
  91.     return OK;
  92. }
  93.  
  94. /*   */
  95.  
  96. static int security_check (msg)
  97. struct type_Qmgr_ProcMsg    *msg;
  98. {
  99.     char    *msg_file = NULL,
  100.         *msg_chan = NULL;
  101.     int    result;
  102.  
  103.     result = TRUE;
  104.     msg_file = qb2str(msg->qid);
  105.     msg_chan = qb2str(msg->channel);
  106.  
  107.     if ((mychan == NULLCHAN) || (strcmp(msg_chan, mychan->ch_name) != 0)) {
  108.         PP_LOG(LLOG_EXCEPTIONS,
  109.             ("Chans/explode_chan channel err: '%s'",msg_chan));
  110.         result = FALSE;
  111.     }
  112.  
  113.     if (msg_file != NULL) free(msg_file);
  114.     if (msg_chan != NULL) free(msg_chan);
  115.     return result;
  116. }
  117.  
  118. /*   */
  119. /* routine to do explode */
  120.  
  121. static struct type_Qmgr_DeliveryStatus *process (arg)
  122. struct type_Qmgr_ProcMsg    *arg;
  123. {
  124.     struct prm_vars            prm;
  125.     Q_struct            que;
  126.     ADDR                *sender = NULL;
  127.     ADDR                *recips = NULL;
  128.     int                rcount, retval;
  129.     struct type_Qmgr_UserList    *ix;
  130.     ADDR                *adr;
  131.     char                *error;
  132.  
  133.     bzero((char *)&que,sizeof(que));
  134.     bzero((char *)&prm,sizeof(prm));
  135.     first_failureDR = TRUE;
  136.     delivery_init(arg->users);
  137.     delivery_setall(int_Qmgr_status_messageFailure);
  138.         
  139.     if (security_check(arg) != TRUE)
  140.         return deliverystate;
  141.  
  142.     if (this_msg != NULL) free(this_msg);
  143.     if (this_chan != NULL) free(this_chan);
  144.  
  145.     this_msg = qb2str(arg->qid);
  146.     this_chan = qb2str(arg->channel);
  147.  
  148.     PP_LOG(LLOG_TRACE,
  149.         ("P2 explode on msg '%s' through '%s'",this_msg,this_chan));
  150.         
  151.     if (rp_isbad(rd_msg(this_msg,&prm,&que,&sender,&recips,&rcount))) {
  152.         PP_LOG(LLOG_EXCEPTIONS,
  153.             ("Chans/explode_chan rd_msg err: '%s'",this_msg));
  154.         rd_end();
  155.         return delivery_setallstate (int_Qmgr_status_messageFailure,
  156.                          "Can't read message");
  157.     }
  158.  
  159.     for (ix = arg->users; ix; ix=ix->next) {
  160.         error = NULLCP;
  161.         err_fatal = NOTOK;
  162.         if ((adr = getnthrecip(&que, ix->RecipientId->parm)) == NULL) {
  163.             PP_LOG(LLOG_EXCEPTIONS,
  164.                 ("Chans/explode_chan : failed to find recipient %d",ix->RecipientId->parm));
  165.             delivery_setstate(ix->RecipientId->parm,
  166.                       int_Qmgr_status_messageFailure,
  167.                       "Unable to find specified recipient");
  168.             continue;
  169.         }
  170.         switch(chan_acheck (adr, mychan, 1, (char **) NULL)) {
  171.             case OK:
  172.             if (processMsg(this_msg,adr,&que,&error) == NOTOK) {
  173.                 if (err_fatal == OK) {
  174.                     PP_LOG(LLOG_EXCEPTIONS,
  175.                            ("Chans/explode_chan : failed to process message '%s' for recipient %d: %s",this_msg,adr->ad_no, error));
  176.                     set_1dr(&que, adr->ad_no, this_msg,
  177.                         DRR_CONVERSION_NOT_PERFORMED,
  178.                         DRD_CONTENT_SYNTAX_ERROR,
  179.                         (error == NULLCP) ? "Unable to parse the p2" : error);
  180.                     delivery_set(adr->ad_no, 
  181.                              (first_failureDR == TRUE) ? int_Qmgr_status_negativeDR : int_Qmgr_status_failureSharedDR);
  182.                     first_failureDR = FALSE;
  183.                 } else
  184.                     delivery_setstate(adr -> ad_no,
  185.                               int_Qmgr_status_messageFailure,
  186.                               (error == NULLCP) ? "" : error);
  187.             } else {
  188.                 adr->ad_rcnt++;
  189.                 wr_ad_rcntno(adr, adr->ad_rcnt);
  190.                 delivery_set(adr->ad_no,int_Qmgr_status_success);
  191.             }
  192.             if (error != NULLCP) free(error);
  193.             break;
  194.             default:
  195.             break;
  196.         }
  197.     }
  198.     if (rp_isbad(retval = wr_q2dr(&que, this_msg))) {
  199.         PP_LOG(LLOG_EXCEPTIONS,
  200.                ("%s wr_q2dr failure '%d'",mychan->ch_name,retval));
  201.         delivery_resetDRs(int_Qmgr_status_messageFailure);
  202.     }
  203.     rd_end();
  204.     q_free (&que);
  205.     prm_free(&prm);
  206.     return deliverystate;
  207. }
  208.  
  209. /*   */
  210.  
  211. extern LIST_BPT    *outbound_bpts, *outbound_hdrs;
  212.  
  213. /* returns ok if processed msg on mychan for recip */
  214. static int processMsg (msg,recip, qp, perr)
  215. char    *msg;
  216. ADDR    *recip;
  217. Q_struct    *qp;
  218. char        **perr;
  219. {
  220.     char        *origdir = NULL,
  221.             *newdir = NULL,
  222.             *encr_str = NULLCP;
  223.     struct stat    statbuf;
  224.     
  225.     if (qid2dir(msg, recip, TRUE, &origdir) != OK) {
  226.         PP_LOG(LLOG_EXCEPTIONS,
  227.             ("Chans/explode_chan original directory not found for recipient %d of message '%s'",recip->ad_no, msg));
  228.         *perr = strdup("Unable to find source directory");
  229.         return NOTOK;
  230.     }
  231.  
  232.     /* temporary change to get new directory name */
  233.     recip->ad_rcnt++;
  234.     if (qid2dir(msg, recip, FALSE, &newdir) != OK) {
  235.         PP_LOG(LLOG_EXCEPTIONS,
  236.             ("Chans/explode_chan couldn't construct new directory name for recipient %d of message '%s'", recip->ad_no, msg));
  237.         *perr = strdup ("Unable to construct new directory");
  238.         return NOTOK;
  239.     }
  240.     recip->ad_rcnt--;
  241.  
  242.     if (stat(newdir, &statbuf) == OK
  243.         && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
  244.             /* new directory already exists, os processing already done */
  245.             if (origdir != NULL) free(origdir);
  246.             if (newdir != NULL) free(newdir);
  247.             return OK;
  248.     }
  249.     x40084 = (lexequ(qp->cont_type, cont_p2) == 0) ? TRUE : FALSE;
  250.        
  251.     /* HACK for undeclared bodyparts that are supported by outchan */
  252.     if (recip -> ad_outchan && recip -> ad_outchan -> li_chan
  253.         && recip -> ad_outchan -> li_chan -> ch_bpt_out)
  254.         outbound_bpts = recip -> ad_outchan -> li_chan -> ch_bpt_out;
  255.     else
  256.         outbound_bpts = NULLIST_BPT;
  257.  
  258.     if (recip -> ad_outchan && recip -> ad_outchan -> li_chan
  259.         && recip -> ad_outchan -> li_chan -> ch_hdr_out)
  260.         outbound_hdrs = recip -> ad_outchan -> li_chan -> ch_hdr_out;
  261.     else
  262.         outbound_hdrs = NULLIST_BPT;
  263.     
  264.  
  265.     if (doSplit(origdir,newdir,msg,qp,perr) != OK)
  266.         return NOTOK;
  267.  
  268.     if (origdir != NULL) free(origdir);
  269.     if (newdir != NULL) free(newdir);
  270.     return OK;
  271. }
  272.  
  273. /*   */
  274. /* explodes p2 in orig into files in new */
  275. static int doSplit (old, new,msg,qp,perr)
  276. char    *old,
  277.     *new,
  278.     *msg;
  279. Q_struct    *qp;
  280. char        **perr;
  281. {
  282.     struct stat    statbuf;
  283.     char        tmpdir[MAXPATHLENGTH], buf[BUFSIZ];
  284.     int        result = OK;
  285.     
  286.     (void) sprintf(tmpdir, "%s/tmp.%s",
  287.                msg,mychan->ch_name);
  288.  
  289.     if (stat(tmpdir, &statbuf) == OK) {
  290.         /* exists so remove it */
  291.         char *cmdline = malloc((unsigned) (strlen("rm -rf ") + strlen(tmpdir) + 1));
  292.         (void) sprintf(cmdline, "rm -rf %s",tmpdir);
  293.         system(cmdline);
  294.         if (cmdline != NULL) free(cmdline);
  295.     }
  296.  
  297.     if (mkdir(tmpdir, 0777) != OK) {
  298.         PP_SLOG(LLOG_EXCEPTIONS, tmpdir,
  299.             ("Can't make directory"));
  300.         (void) sprintf(buf,
  301.                    "Failed to make temporary directory '%s'",
  302.                    tmpdir);
  303.         *perr = strdup(buf);
  304.         return NOTOK;
  305.     }
  306.     result = unflatten(old,tmpdir, x40084, qp, perr);
  307.     if ((result == OK) && (rename(tmpdir,new) == -1)) {
  308.         PP_SLOG(LLOG_EXCEPTIONS, "rename",
  309.             ("Can't rename directory '%s' to '%s'",
  310.              tmpdir, new));
  311.         result = NOTOK;
  312.     }
  313.     return result;
  314. }
  315.  
  316. static ADDR *getnthrecip(que, num)
  317. Q_struct    *que;
  318. int        num;
  319. {
  320.     ADDR *ix = que->Raddress;
  321.  
  322.     if (num == 0)
  323.         return que->Oaddress;
  324.     while ((ix != NULL) && (ix->ad_no != num))
  325.         ix = ix->ad_next;
  326.     return ix;
  327. }
  328.  
  329.